/*
 * To change this template, choose Tools | Templates and open the template in
 * the editor.
 */
package bea.cliente.core;

import bea.cliente.environment.SunLightNode;
import com.jme3.app.Application;
import com.jme3.app.state.AbstractAppState;
import com.jme3.app.state.AppStateManager;
import com.jme3.light.AmbientLight;
import com.jme3.light.DirectionalLight;
import com.jme3.light.PointLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.post.SceneProcessor;
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import com.jme3.shadow.BasicShadowRenderer;
import com.jme3.shadow.PssmShadowRenderer;
import com.jme3.shadow.PssmShadowRenderer.CompareMode;
import com.jme3.shadow.PssmShadowRenderer.FilterMode;
import java.io.File;
import java.io.IOException;
import java.util.jar.JarFile;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Ivan da Silveira
 */
public class WorldManagerState extends AbstractAppState {

    protected GameSettings gameSettings;
    protected Game game;
    // SHADOW
    protected SceneProcessor shadowSceneProcess;
    //LIGHTS
    protected AmbientLight ambientLightMain;
    protected SunLightNode sunLightNode;

    public WorldManagerState(Game _game) {
        game = _game;
        gameSettings = game.gameSettings;
    }

    @Override
    public void initialize(AppStateManager stateManager, Application app) {
        // SHADOW
        if (gameSettings.hasShadow()) {
            initShadow();
        }

        // inicializa as luzes
        initLights();

        // inicializa as arenas
        initArenas();

        // call parent at the end
        super.initialize(stateManager, app);
    }

    @Override
    public void update(float tpf) {
        /**
         * Implement here shadow direction by time // UPDATE SHADOW DIRECTION
         * Vector3f shadowDirection = new Vector3f(0, 1, 0); if
         * (shadowSceneProcess instanceof BasicShadowRenderer) {
         * ((BasicShadowRenderer)
         * shadowSceneProcess).setDirection(shadowDirection.normalizeLocal()); }
         * else { ((PssmShadowRenderer)
         * shadowSceneProcess).setDirection(shadowDirection.normalizeLocal()); }
         */
    }

    /**
     * Inicializa variaveis de sombra
     */
    private void initShadow() {
        switch (gameSettings.getShadowType()) {
            // inicialize PSSM shadow
            case (GameSettings.SHADOW_PSSM):
                shadowSceneProcess = new PssmShadowRenderer(game.getAssetManager(), 1024, 4);
                ((PssmShadowRenderer) shadowSceneProcess).setDirection(new Vector3f(-1, -1, -1).normalizeLocal());
                ((PssmShadowRenderer) shadowSceneProcess).setLambda(0.55f);
                ((PssmShadowRenderer) shadowSceneProcess).setShadowIntensity(0.6f);
                ((PssmShadowRenderer) shadowSceneProcess).setCompareMode(CompareMode.Software);
                ((PssmShadowRenderer) shadowSceneProcess).setFilterMode(FilterMode.PCF4);
                //pssmRenderer.displayDebug();
                break;
            default:
                // by default inicialize BASIC shadow
                shadowSceneProcess = new BasicShadowRenderer(game.getAssetManager(), 4096);
                ((BasicShadowRenderer) shadowSceneProcess).setDirection(new Vector3f(1, 1, 1).normalizeLocal());
                break;
        }
        game.getViewPort().addProcessor(shadowSceneProcess);
        game.rootNode.setShadowMode(ShadowMode.Off);
    }

    /**
     * Método responsável pela inicialização da 'light environments'
     */
    private void initLights() {
        DirectionalLight dl = new DirectionalLight();
        Vector3f lightDir = new Vector3f(-1, -1, .5f).normalizeLocal();
        dl.setDirection(lightDir);
        dl.setColor(new ColorRGBA(.9f, .9f, .9f, 1));
        game.rootNode.addLight(dl);

        dl = new DirectionalLight();
        dl.setDirection(new Vector3f(1, 0, -1).normalizeLocal());
        dl.setColor(new ColorRGBA(1, 1, 1, 1));
        dl.setColor(new ColorRGBA(.4f, .4f, .4f, 1));
        game.rootNode.addLight(dl);

        // ambiente light
        ambientLightMain = new AmbientLight();
        ambientLightMain.setColor(ColorRGBA.White);
        //game.rootNode.addLight(ambientLightMain);
        // sun light
        sunLightNode = new SunLightNode("sun:Node");
        //sunLightNode.initialize();
        //game.rootNode.attachChild(sunLightNode);
    }

    /**
     * Método responsável pela inicialização da 'light environments'
     */
    private void initArenas() {
        game.getViewPort().setBackgroundColor(ColorRGBA.DarkGray);
        Material mat = new Material(game.getAssetManager(), "Common/MatDefs/Light/Lighting.j3md");
        mat.setFloat("Shininess", 12);
        mat.setBoolean("UseMaterialColors", true);
        mat.setColor("Ambient", ColorRGBA.Gray);
        mat.setColor("Diffuse", ColorRGBA.White);
        mat.setColor("Specular", ColorRGBA.Gray);
        //mat.setTexture("ColorMap", game.getAssetManager().loadTexture("Textures/ColoredTex/Monkey.png"));

        //Quad pl = new Quad(1, 1);
        Box box = new Box(Vector3f.ZERO, 5, 5, 5);
        Geometry gBox = new Geometry("gBox", box);
        gBox.setMaterial(mat);
        gBox.setShadowMode(ShadowMode.Off);
        //gBox.rotate(FastMath.DEG_TO_RAD * -90.0f, 0, 0);
        //gBox.setLocalScale(10f);
        gBox.setLocalTranslation(-20f, 0, 20f);
        game.rootNode.attachChild(gBox);
        
        try {
            JarFile jarFile = new JarFile("/scenes.jar");
        } catch (IOException ex) {
            Logger.getLogger(WorldManagerState.class.getName()).log(Level.SEVERE, null, ex);
        }

        File sceneFolder = new File("scenes/");
        System.out.println(sceneFolder.getAbsoluteFile());
        File[] arenaFiles = sceneFolder.listFiles();
        if (arenaFiles != null) {
            for (int i = 0; i < arenaFiles.length; i++) {
                if (arenaFiles[i].isFile()) {
                    //filename.add(arenaFiles[i].getName());
                    System.out.println(arenaFiles[i].getName());
                }
            }
        }
    }

    /**
     * Método responsável pela inicialização da 'water environments'
     */
    private void initWater() {
    }
}
